const fse = require('fs-extra');
const fs = require('fs');
const puppeteer = require('puppeteer');
const {
  base,
  index,
  index2,
  attributeMap,
  monsterTypeMap,
  spellTypeMap,
  trapTypeMap,
  typeMqp,
  account,
} = require('./const.js');
const { getData, getMultiData } = require('../data.js');
const { variation } = require('../cardNode.js');
const chalk = require('chalk');

let browser;
const pageMap = {};
const getPage = async (name, config = {
    headless: true,
    timeout: 600000,
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
    handleSIGINT: false
}) => {
  if (!browser) {
    browser = await puppeteer.launch(config);
  }
  
  if (!pageMap[name]) {
    pageMap[name] = await browser.newPage();
  }

  return pageMap[name];
}

const login = async () => {
  const { userName, password } = account;

  const page = await getPage('login');
  
  await page.goto(`${base}/account/login.aspx?errCode=exp`);

  await page.type('input#username.login-pinput', userName, { delay: 100 });
  await page.type('input[type=password].login-pinput', password, { delay: 100 });
  await page.click('a[rel=S_login]');

  // 登陆成功
  return new Promise(resolve => {
    page.on('framenavigated', () => {
      console.log(`${userName} 登陆成功`);

      resolve(true);
    });
  });
};

const getHtml = async (url, page) => {
  if (!page) {
    page = await getPage('default');
  }
  
  // await page.setRequestInterception(true);

  return new Promise(async (resolve) => {
    page.on('domcontentloaded', async () => {
      const html = await page.content();
      resolve(html);
    });

    // page.on('request', async (request) => {
    //   const loginCheck = `${base}/Manage/CustomValidator.ashx`;

    //   if (request.url() === loginCheck) {
    //     await request.respond({
    //       status: 200,
    //       headers: {
    //         'Access-Control-Allow-Origin': '*',
    //       },
    //       contentType: 'application/json; charset=utf-8',
    //       body: JSON.stringify({
    //         info: 'ymssx',
    //         status: '1',
    //       }),
    //     });
    //   }
    //   else {
    //     await request.continue();
    //   }
    // });

    page.goto(url, { waitUntil: 'domcontentloaded' });
  });
};

const getPicUrlFromPuzz = async (url) => {
  const page = await getPage('puzz');

  const html = await getHtml(`${base}/vote/puzzle.aspx?v=${url}`, page);
  const srcList = html.match(/(?<=src=").*\.(jpg|png)(?=\")/g) || [];
  
  if (srcList && srcList.length > 0) {
    return srcList[0];
  }
};

const getPicUrl = async (url) => {
  const page = await getPage('index');

  const html = await getHtml(url, page);
  const srcList = html.match(/(?<=goPuzzles?\(\').*(?=\'\))/g) || [];
  
  if (srcList.length > 0) {
    const picName = srcList[0];
    const re = /.(png|jpg)$/g;

    if (re.test(picName)) {
      // 可以直接得到图片地址
      return `${base}/yugioh/LargePic/${srcList[0]}`;
    } else {
      // 前往拼图页面获取
      return await getPicUrlFromPuzz(picName);
    }
  }
};

const downloadPic = async (url, savePath = './pics/test.jpg') => {
  const page = await getPage('img');
  var viewSource = await page.goto(url);
  await fse.outputFile(savePath, await viewSource.buffer());
  console.log(`下载成功: ${chalk.underline.blue(url)}`);
};

const getPageUrlFromData = data => {
  const { _id, type, type2, level, attribute } = data;
  
  const password = String(_id).length >= 8
    ? String(_id)
    : new Array(8 - String(_id).length).fill('0').join('') + _id;

  if (type === 'monster') {
    if (type2 === 'xg') {
      return `${base}/html/0/${attributeMap[attribute]}/${level}/${password}.html`;
    } else if (type2 === 'lj') {
      return `${base}/html/${monsterTypeMap[type2]}/${password}.html`;
    } else {
      return `${base}/html/${monsterTypeMap[type2]}/${level}/${password}.html`;
    }
  } else {
    if (type2 === 'tc') {
      return `${base}/html/${typeMqp[type][type2]}/${password[0]}/${password}.html`;
    } else {
      return `${base}/html/${typeMqp[type][type2]}/${password}.html`;
    }
  }
};

const getDataFromId = async (id) => {
  const originData = await getData(id);
  return variation(originData);
};

const getCardPic = async (dataOrId, index = 1, num = 1, saveDir = '../../public/pics/500/') => {
  const line = '--------------------------------------------';

  let data;
  let id;
  if (typeof dataOrId === 'string') {
    id = dataOrId;
    try {
      data = await getDataFromId(dataOrId);
    } catch {
      console.log(`\n${line}\n${chalk.red(`× ${index}/${num}`)} id: ${id}  读取失败\n`);
      throw(new Error('读取失败'));
    }
  } else {
    data = dataOrId;
    id = dataOrId._id;
  }

  const savePath = `${saveDir}${id}.jpg`;
  
  return new Promise(async (resolve, reject) => {
    fs.exists(savePath, async (exists) => {
      if (exists) {
        resolve();
        return;
      }
    
      console.log(`\n${line}\n${chalk.green(`√ ${index}/${num}`)} id: ${id}  卡名: ${chalk.yellow(data.name)}\n`);
  
      try {
        const pageUrl = getPageUrlFromData(data);
        const picUrl = await getPicUrl(pageUrl);
    
        await downloadPic(picUrl, savePath);
        resolve();
      } catch {
        console.log('下载失败');
        reject(new Error('下载失败'));
      }
    });
  });
};

module.exports = {
  login,
  getCardPic,
};
